package com.ls.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ls.controller.customer.model.TimeModel;
import com.ls.controller.orderrecord.model.*;
import com.ls.entity.*;
import com.ls.enums.RoleEnum;
import com.ls.mapper.OrderRecordMapper;
import com.ls.service.ICustomerService;
import com.ls.service.IOrderRecordService;
import com.ls.service.IScoreRecordService;
import com.ls.utils.ResultData;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.ls.constant.SystemConstants.*;
import static com.ls.enums.OrderRecordEnum.getOrderRecordEnum;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author pengyu
 * @since 2024-06-28
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderRecordServiceImpl extends ServiceImpl<OrderRecordMapper, OrderRecord> implements IOrderRecordService {
    @Lazy
    private final ICustomerService customerService;
    @Lazy
    private final IScoreRecordService scoreRecordService;

    /**
     * 查询订单记录分页列表
     */
    @Override
    public ResultData pageListApp(OrderRecordModel model) {
        LambdaQueryWrapper<OrderRecord> wrapper = new LambdaQueryWrapper<OrderRecord>()
                .eq(model.getCustomerId() != null, OrderRecord::getCustomerId, model.getCustomerId())
                .like(StringUtils.isNotBlank(model.getOrderNum()), OrderRecord::getOrderNum, model.getOrderNum())
                .like(StringUtils.isNotBlank(model.getThirdOrderNumber()), OrderRecord::getThirdOrderNumber, model.getThirdOrderNumber())
                .eq(model.getProductType() != null, OrderRecord::getProductType, model.getProductType())
                .eq(model.getPeriod() != null, OrderRecord::getPeriod, model.getPeriod())
                .eq(model.getPayType() != null, OrderRecord::getPayType, model.getPayType())
                .eq(model.getOrderStatus() != null, OrderRecord::getOrderStatus, model.getOrderStatus())
                .ge(StringUtils.isNotBlank(model.getBeginSt()), OrderRecord::getCreateTime, model.getBeginSt())
                .le(StringUtils.isNotBlank(model.getEndSt()), OrderRecord::getCreateTime, model.getEndSt())
                .orderByDesc(OrderRecord::getCreateTime);
        List<OrderRecord> orderRecords = this.baseMapper.selectList(wrapper);
        Map<Boolean, List<OrderRecord>> partitioned = orderRecords.stream()
                .filter(record -> record.getSmsType() != null) // 过滤空值
                .collect(Collectors.partitioningBy(
                        record -> record.getSmsType() == NUMBER_0||record.getSmsType()== NUMBER_1
                ));

// 构建明确的分组结果结构
        Map<String, List<OrderRecord>> result = new LinkedHashMap<>();
        //过期失效的订单
        result.put("expiredOrders", partitioned.getOrDefault(false, Collections.emptyList()));
        //正常订单
        result.put("activeOrders", partitioned.getOrDefault(true, Collections.emptyList()));

        //查询这些模板ID 是不是在使用中;如果在的话，就 设置 在使用中
        return ResultData.successData(result);
    }
    /**
     * 查询订单记录分页列表
     */
    @Override
    public ResultData pageList(QueryOrderRecordModel model) {
        LambdaQueryWrapper<OrderRecord> wrapper = new LambdaQueryWrapper<OrderRecord>()
                .eq(model.getCustomerId() != null, OrderRecord::getCustomerId, model.getCustomerId())
                .like(StringUtils.isNotBlank(model.getOrderNum()), OrderRecord::getOrderNum, model.getOrderNum())
                .like(StringUtils.isNotBlank(model.getThirdOrderNumber()), OrderRecord::getThirdOrderNumber, model.getThirdOrderNumber())
                .eq(model.getProductType() != null, OrderRecord::getProductType, model.getProductType())
                .eq(model.getPeriod() != null, OrderRecord::getPeriod, model.getPeriod())
                .eq(model.getPayType() != null, OrderRecord::getPayType, model.getPayType())
                .like(model.getPhone() != null, OrderRecord::getPhone, model.getPhone())
                .eq(model.getOrderStatus() != null, OrderRecord::getOrderStatus, model.getOrderStatus())
                .ge(StringUtils.isNotBlank(model.getBeginSt()), OrderRecord::getCreateTime, model.getBeginSt())
                .le(StringUtils.isNotBlank(model.getEndSt()), OrderRecord::getCreateTime, model.getEndSt())
                .orderByDesc(OrderRecord::getCreateTime);
        Page page = new Page(model.getPageNum(), model.getPageSize());
        IPage<OrderRecord> dtoIPage = this.baseMapper.selectPage(page, wrapper);
        //查询这些模板ID 是不是在使用中;如果在的话，就 设置 在使用中
        return ResultData.successData(dtoIPage);
    }

    /**
     * 修改订单数据
     */
    @Override
    public ResultData changeOrder(String orderNum, String orderNumber, LocalDateTime payTime) {
        //实现根据orderNum查询订单记录
        OrderRecord orderRecord = getOrderRecordByOrderNum(orderNum);
        log.info("订单记录：{}",orderRecord.getThirdOrderNumber());
        if (orderRecord == null) {
            return ResultData.successData(new HashMap<String, Object>() {{
                put("isOk", false);
            }});
        }
        if (StringUtils.isNotEmpty(orderRecord.getThirdOrderNumber())) {
            return ResultData.successData(new HashMap<String, Object>() {{
                put("isOk", false);
            }});
        }
        orderRecord.setThirdOrderNumber(orderNumber);
        orderRecord.setPayTime(payTime);
        orderRecord.setOrderStatus(PAY_STATUS_SUCCESS);
        log.info("修改订单记录1：{}",orderRecord);
        Customer customer = customerService.getById(orderRecord.getCustomerId());
        log.info("修改订单记录2：{}",customer);
        if (orderRecord.getProductType() == PRODUCT_TYPE_SMS) {
            //短信未过期
            if (customer.getSmsExpireTime()!=null&&customer.getSmsExpireTime().isAfter(LocalDateTime.now())){
                orderRecord.setSmsType(SMS_PACKAGE_STATUS_DEFAULT);
                orderRecord.setApplyTime(customer.getSmsExpireTime().plusDays(1));
                orderRecord.setExpireTime(customer.getSmsExpireTime().plusMonths(orderRecord.getPeriod()));
            }else {
                orderRecord.setSmsType(SMS_PACKAGE_STATUS_TRUE);
                orderRecord.setApplyTime(LocalDateTime.now());
                orderRecord.setExpireTime(LocalDateTime.now().plusMonths(orderRecord.getPeriod()));
            }
        } else if(orderRecord.getProductType() == PRODUCT_TYPE_MEMBER) {
            log.info("会员订单：{}",orderNumber);
            //判断是不是会员
            if (customer.getMemberStatus() == MEMBER_STATUS_TRUE) {
                orderRecord.setSmsType(SMS_PACKAGE_STATUS_DEFAULT);
                orderRecord.setApplyTime(customer.getMemberExpireTime().plusDays(1));
                orderRecord.setExpireTime(customer.getMemberExpireTime().plusMonths(orderRecord.getPeriod()));
            } else {
                orderRecord.setSmsType(SMS_PACKAGE_STATUS_TRUE);
                orderRecord.setApplyTime(LocalDateTime.now());
                orderRecord.setExpireTime(LocalDateTime.now().plusMonths(orderRecord.getPeriod()));
            }
        }else{
            //加量包由于直接加入短信余额，实现购买就立即过期
            orderRecord.setSmsType(SMS_PACKAGE_STATUS_TRUE);
            // 增加空值检查并设置默认值
            LocalDateTime smsClearTime = customer.getSmsClearTime() != null
                    ? customer.getSmsClearTime()
                    : LocalDateTime.now();
            LocalDateTime memberClearTime = customer.getMemberClearTime() != null
                    ? customer.getMemberClearTime()
                    : LocalDateTime.now();

            if (smsClearTime.isBefore(memberClearTime)) {
                orderRecord.setExpireTime(smsClearTime);
                orderRecord.setApplyTime(LocalDateTime.now());
                orderRecord.setExpireType(PRODUCT_TYPE_MEMBER);
            } else {
                orderRecord.setExpireTime(memberClearTime);
                orderRecord.setApplyTime(LocalDateTime.now());
                orderRecord.setExpireType(PRODUCT_TYPE_SMS);
            }
        }
        log.info("修改订单记录：{}",orderRecord);
        orderRecord.updateById();
        return ResultData.successData(new HashMap<String, Object>() {{
            put("isOk", true);
            put("customerId", orderRecord.getCustomerId());
            put("productId", orderRecord.getProductId());
            put("orderRecordId", orderRecord.getOrderRecordId());
        }});
    }

    /**
     * 退款
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultData refund(Long orderRecordId, BigDecimal money) {
        OrderRecord orderRecord = getById(orderRecordId);
        orderRecord.setOrderStatus(PAY_STATUS_REFUND_SUCCESS);
        orderRecord.setSmsType(SMS_PACKAGE_EFFECT_STATUS_FALSE);
        orderRecord.setExpireTime(LocalDateTime.now());
        orderRecord.updateById();
        Customer customer = customerService.getById(orderRecord.getCustomerId());
        //修改积分
        ScoreRecord scoreRecord = scoreRecordService.getScore(orderRecord.getOrderRecordId());
        if (scoreRecord!=null){
            scoreRecord.setValidFlag(VALID_FALSE);
            scoreRecordService.save(scoreRecord);
            Integer score= Math.toIntExact(customer.getMemberScore() - scoreRecord.getChangeScore());
            log.info("积分：{}",score);
            customer.setMemberScore(score);
            customer.setMemberLevel(getOrderRecordEnum(score));
        }
        Integer count=0;
        if (orderRecord.getProductType()==PRODUCT_TYPE_MEMBER){
            LocalDateTime time=customer.getMemberExpireTime();
            if (time.minusMonths(orderRecord.getPeriod()).isAfter(LocalDateTime.now())){
                customer.setMemberExpireTime(customer.getMemberExpireTime().minusMonths(orderRecord.getPeriod()));
            }else {
                Integer MessageNum=0;
                Integer SmsTotal=0;
                if (customer.getMessageNum()>orderRecord.getMonthSmsQuantity()){
                    MessageNum=customer.getMessageNum()-orderRecord.getMonthSmsQuantity();
                    SmsTotal=orderRecord.getMonthSmsQuantity();
                }else{
                    SmsTotal=customer.getMessageNum();
                }
                customer.setMemberExpireTime(LocalDateTime.now());
                customer.setMemberClearTime(LocalDateTime.now());
                customer.setSmsTotal(customer.getSmsTotal()-SmsTotal);
                customer.setCurrentQuantity(customer.getCurrentQuantity()-customer.getMessageNumTotal());
                customer.setMessageNumTotal(customer.getMessageNumTotal()-orderRecord.getMonthSmsQuantity());
                customer.setMessageNum(MessageNum);
                customer.setMemberStatus(MEMBER_STATUS_FALSE);
                customer.setRoleId(RoleEnum.COMMON.roleType);
            }
        }else if (orderRecord.getProductType()==PRODUCT_TYPE_SMS){
            LocalDateTime time=customer.getSmsExpireTime();
            if (time.minusMonths(orderRecord.getPeriod()).isAfter(LocalDateTime.now())){
                customer.setSmsExpireTime(customer.getSmsExpireTime().minusMonths(orderRecord.getPeriod()));
                log.info("处理短信套餐1111");
            }else{
                customer.setSmsExpireTime(LocalDateTime.now());
                customer.setSmsClearTime(LocalDateTime.now());
                Integer SmsThaliNum=0;
                Integer SmsTotal=0;
                if (customer.getSmsThaliNum()>orderRecord.getMonthSmsQuantity()){
                    SmsThaliNum=customer.getSmsThaliNum()-orderRecord.getMonthSmsQuantity();
                    SmsTotal=orderRecord.getMonthSmsQuantity();
                }else{
                    SmsTotal=customer.getSmsThaliNum();
                }
                customer.setSmsTotal(customer.getSmsTotal()-SmsTotal);
                customer.setCurrentQuantity(customer.getCurrentQuantity()-customer.getSmsThaliNumTotal());
                customer.setSmsThaliNumTotal(customer.getSmsThaliNumTotal()-orderRecord.getMonthSmsQuantity());
                customer.setSmsThaliNum(SmsThaliNum);
                log.info("处理短信套餐2222");
            }
        }else {
            if (orderRecord.getExpireType()==PRODUCT_TYPE_MEMBER){
                if (customer.getMessageNum()>orderRecord.getMonthSmsQuantity()){
                    count=orderRecord.getMonthSmsQuantity();
                }else{
                    count=customer.getMessageNum();
                }
                customer.setMessageNumTotal(customer.getMessageNumTotal()-orderRecord.getMonthSmsQuantity());
                customer.setMessageNum(customer.getMessageNum()-count);
            }else{
                if (customer.getSmsThaliNum()>orderRecord.getMonthSmsQuantity()){
                    count=orderRecord.getMonthSmsQuantity();
                }else{
                    count=customer.getSmsThaliNum();
                }
                customer.setSmsThaliNumTotal(customer.getSmsThaliNumTotal()-orderRecord.getMonthSmsQuantity());
                customer.setSmsThaliNum(customer.getSmsThaliNum()-count);
            }
            customer.setCurrentQuantity(customer.getCurrentQuantity()-orderRecord.getMonthSmsQuantity());
            customer.setSmsTotal(customer.getSmsTotal()-count);
        }
        customer.setConsumeAmount(customer.getConsumeAmount().subtract(money));
        customer.setOrderTimes(customer.getOrderTimes() - 1);
        boolean updateResult = customerService.updateById(customer);
        if (!updateResult) {
            log.error("客户信息更新失败，customerId: {}", customer.getCustomerId());
            throw new RuntimeException("客户信息更新失败");
        }
        return ResultData.successData(true);
    }

    @Override
    public BigDecimal sumTodayRecharge(LocalDateTime start, LocalDateTime end) {
        return this.baseMapper.selectTodayRechargeAmount(start, end);
    }

    /**
     * 统计信息充值产品
     */
    @Override
    public ResultData getDataPay(TimeModel model) {
        // 获取所有订单记录
        List<OrderRecord> records = list(new LambdaQueryWrapper<OrderRecord>()
                .eq(OrderRecord::getOrderStatus, PAY_STATUS_SUCCESS)
                .between(StringUtils.isNotBlank(model.getBeginSt()), OrderRecord::getPayTime, model.getBeginSt()+ " 00:00:00", model.getEndSt()+ " 23:59:59")
        );
        // 按产品类型和周期双重分组统计
        Map<Integer, Map<Integer, Long>> productCounts = records.stream()
                .collect(Collectors.groupingBy(OrderRecord::getProductType,
                        Collectors.groupingBy(OrderRecord::getPeriod, Collectors.counting())));

        // 组装返回数据结构
        List<PayDataModel> result = new ArrayList<>();
        productCounts.forEach((productType, periodMap) -> {
            periodMap.forEach((period, count) -> {
                String productName = productType == PRODUCT_TYPE_MEMBER ? "会员套餐" : "短信套餐";
                // 添加周期信息到产品名称
                result.add(new PayDataModel(productName + "(" + period + "个月)", count));
            });
        });
        return ResultData.successData(result);
    }

    /**
     * 统计会员充值趋势
     */
    @Override
    public ResultData getDataRecharge(TimeModel model) {
        LocalDate end = StringUtils.isNotBlank(model.getEndSt()) ? LocalDate.parse(model.getEndSt()) : LocalDate.now();
        LocalDate start = StringUtils.isNotBlank(model.getBeginSt()) ? LocalDate.parse(model.getBeginSt()) : end.minusMonths(12).withDayOfMonth(1);

        // 查询成功支付的会员订单
        List<OrderRecord> records = list(new LambdaQueryWrapper<OrderRecord>()
                .eq(OrderRecord::getOrderStatus, PAY_STATUS_SUCCESS)
                .eq(OrderRecord::getProductType, PRODUCT_TYPE_MEMBER)
                .between(OrderRecord::getPayTime, start+ " 00:00:00", end+ " 23:59:59")
        );

        Map<String, RechargeDataModel> monthlyStats = new HashMap<>();
        records.forEach(record -> {
            String monthKey = record.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM"));
            monthlyStats.computeIfAbsent(monthKey, k -> new RechargeDataModel(k, 0L, BigDecimal.ZERO))
                    .addCountAndAmount(1L, record.getFee());
        });

        // 生成完整月份序列
        List<RechargeDataModel> result = new ArrayList<>();
        LocalDate currentDate = start;
        while (!currentDate.isAfter(end)) {
            String monthKey = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            RechargeDataModel model1 = monthlyStats.getOrDefault(monthKey,
                    new RechargeDataModel(monthKey, 0L, BigDecimal.ZERO));
            result.add(model1);
            currentDate = currentDate.plusMonths(1);
        }

        return ResultData.successData(result);
    }

    /**
     * 统计会员增长趋势
     */
    @Override
    public ResultData getDataMember(TimeModel model) {

        // 获取近一年时间范围
        LocalDate end = StringUtils.isNotBlank(model.getEndSt()) ? LocalDate.parse(model.getEndSt()) : LocalDate.now();
        LocalDate start = StringUtils.isNotBlank(model.getBeginSt()) ? LocalDate.parse(model.getBeginSt()) : end.minusMonths(12).withDayOfMonth(1);

        // 查询成功支付的会员订单
        List<OrderRecord> records = list(new LambdaQueryWrapper<OrderRecord>()
                .eq(OrderRecord::getOrderStatus, PAY_STATUS_SUCCESS)
                .eq(OrderRecord::getProductType, PRODUCT_TYPE_MEMBER)
                .between(OrderRecord::getPayTime, start+ " 00:00:00", end+ " 23:59:59"));

        // 按月份分组统计
        Map<String, Long> monthlyCounts = records.stream()
                .collect(Collectors.groupingBy(
                        record -> record.getPayTime().format(DateTimeFormatter.ofPattern("yyyy-MM")),
                        Collectors.counting()
                ));

        // 生成完整月份序列（包含无数据的月份）
        List<MemberDataModel> result = new ArrayList<>();
        LocalDate currentDate = start;
        while (!currentDate.isAfter(end)) {
            String monthKey = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            Long count = monthlyCounts.getOrDefault(monthKey, 0L);
            result.add(new MemberDataModel(monthKey, count));
            currentDate = currentDate.plusMonths(1);
        }


        return ResultData.successData(result);
    }
    /** 订单过期 */
    @Override
    public Boolean orderExpire(String orderNum){
        OrderRecord orderRecord = getOrderRecordByOrderNum(orderNum);
        orderRecord.setOrderStatus(PAY_STATUS_AUTO_CANCEL);
        orderRecord.setExpireTime(LocalDateTime.now());
        return updateById(orderRecord);
    }
    public OrderRecord getOrderRecordByOrderNum(String orderNum){
        OrderRecord orderRecord = this.baseMapper.getOrderRecordByOrderNum(orderNum);
        return orderRecord;
    }
}
